package com.douqu.game.activity.server.netty;


import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.bean.core.buffer.ByteBuffer;
import com.bean.core.util.TimeUtils;
import com.douqu.game.activity.GameServer;
import com.douqu.game.activity.database.model.ActivityCampModel;
import com.douqu.game.activity.entity.MainServerInfo;
import com.douqu.game.activity.entity.camp.MatchTeam;
import com.douqu.game.activity.manager.ActivityCampManager;
import com.douqu.game.activity.manager.LoadManager;
import com.douqu.game.activity.server.SpringContext;
import com.douqu.game.core.e.E_ApplyCampActivityType;
import com.douqu.game.core.entity.activity.MatchBaseInfo;
import com.douqu.game.core.entity.battle.BattleResultParamCampSingle;
import com.douqu.game.core.factory.CodeFactory;
import com.douqu.game.core.factory.ConfigFactory;
import com.douqu.game.core.factory.ConstantFactory;
import com.douqu.game.core.util.BufferUtils;
import com.douqu.game.core.util.LogUtils;
import com.douqu.game.core.util.SendUtils;
import com.douqu.game.core.util.CoreUtils;
import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;

/**
* Created by Administrator on 2016/11/9.
*/
public class NettyTCPClientHandler extends ChannelInboundHandlerAdapter {

    private MainServerInfo serverInfo;

    public NettyTCPClientHandler(MainServerInfo serverInfo)
    {
        this.serverInfo = serverInfo;
    }

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception
    {
        cause.printStackTrace();

        LogUtils.info(cause.getLocalizedMessage());

        ctx.close();
    }

    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception
    {
        ByteBuf byteBuf = (ByteBuf) msg;
        int code = BufferUtils.readShort(byteBuf);

        LogUtils.info(serverInfo + " 收到code:" + code + ",data length:" + byteBuf.readableBytes());

        try{
            if(CodeFactory.ACTIVITY_SERVER_INIT == code)
            {
                ByteBuffer buffer = CoreUtils.toByteBuffer(byteBuf);
                String rmi = buffer.readUTF();

//                String s1 = rmi.substring(0, 6);
//                String s2 = rmi.substring(rmi.lastIndexOf(":"), rmi.length());
//                String url = s1 + serverInfo.getHost() + s2;
                String url = rmi;
                LogUtils.info("获取到RMI地址 -> " + url);
                serverInfo.startRMI(url);
                /**
                 * 读到这里说明活动服收到主服回调
                 * 设置玩家的奖励已经领取过了
                 */
                if (buffer.readBoolean()){
                    ActivityCampManager activityCampManager = GameServer.getInstance().getActivityCampManager();
                    activityCampManager.setRewardTrue(serverInfo.getId());
                }

                return;
            }
            else if (CodeFactory.ACTIVITY_CAMP_STATUS == code){
                //收到状态回调 说明已经成功的发放奖励了
                ByteBuffer buffer = CoreUtils.toByteBuffer(byteBuf);
                if (buffer.readBoolean()){
                    ActivityCampManager activityCampManager = GameServer.getInstance().getActivityCampManager();
                    activityCampManager.setRewardTrue(serverInfo.getId());
                }
                return;
            }

            if(!serverInfo.isConnectSuccess())
            {
                LogUtils.error("主服务器没有完全连接成功,请检查!");
                serverInfo.stop();
                GameServer.getInstance().removeMainServerInfo(serverInfo);
                return;
            }

            if(CodeFactory.ACTIVITY_CAMP_APPLY_SUCCESS == code)
            {
                ByteBuffer buffer = CoreUtils.toByteBuffer(byteBuf);
                String playerInfo = buffer.readUTF();
                E_ApplyCampActivityType type = E_ApplyCampActivityType.valueOf(buffer.readUTF());
                MatchBaseInfo baseInfo = JSON.parseObject(playerInfo, MatchBaseInfo.class);

                LogUtils.info(serverInfo + " =-> 收到报名成功的消息,玩家ID -> " + baseInfo.getObjectIndex() + "," + baseInfo.getName() + ", type -> " + type);

                GameServer.getInstance().getActivityCampManager().addMatchPlayer(baseInfo, type);

                serverInfo.sendApplySuccess(baseInfo.getObjectIndex(), type);
            }
            else if(CodeFactory.ACTIVITY_CAMP_MATCH_SUCCESS == code)
            {
                ByteBuffer buffer = CoreUtils.toByteBuffer(byteBuf);
                JSONObject jsonObject = JSON.parseObject(buffer.readUTF());
                String playerIndex = jsonObject.getString(CodeFactory.KEY_PLAYER_INDEX);
                String teamIndex = jsonObject.getString(CodeFactory.KEY_TEAM_INDEX);
                boolean flag = jsonObject.getBoolean(CodeFactory.KEY_FLAG);
                boolean free = jsonObject.getBoolean(CodeFactory.KEY_FREE);
                LogUtils.info("匹配成功后通知主服,收到回应消息! -> teamIndex:" + teamIndex + ", playerIndex:" + playerIndex + " flag:" + flag + " free:" + free);
                MatchTeam matchTeam = GameServer.getInstance().getActivityCampManager().getMatchTeam(teamIndex);
                if(matchTeam == null)
                {
                    LogUtils.error("没有匹配记录 -> teamIndex:" + teamIndex + ", playerIndex:" + playerIndex);
                    return;
                }
                if(flag)
                {
                    LogUtils.info("进行下一步,通知战斗服务器或等待对手玩家 -> teamIndex:" + teamIndex + ", playerIndex:" + playerIndex);
                    matchTeam.ready(playerIndex, free);
                }
                else
                {
                    if(jsonObject.containsKey(CodeFactory.KEY_RESULT))
                    {
                        BattleResultParamCampSingle resultParam = JSONObject.parseObject(jsonObject.getString(CodeFactory.KEY_RESULT), BattleResultParamCampSingle.class);
                        GameServer.getInstance().getActivityCampManager().campBattleResult(playerIndex, resultParam, null, E_ApplyCampActivityType.NO_BATTLE);
                    }

                    GameServer.getInstance().getActivityCampManager().removeMatchTeam(matchTeam);
                }
            }
            else if(CodeFactory.LOAD_DATA == code)
            {
                ByteBuffer buffer = CoreUtils.toByteBuffer(byteBuf);
                String path = buffer.readUTF();
                String version = buffer.readUTF();

                LogUtils.info("收到主服务器发过来的更新配置文件消息,版本号 -> " + version + " 路径 -> " + path);

                LoadManager.loadFromCos(path, version);
            }
            else if(CodeFactory.UPDATE_LOG_CONFIG == code)
            {
                ByteBuffer buffer = CoreUtils.toByteBuffer(byteBuf);

                if(buffer.available() > 0)
                {
                    String logLevel = buffer.readUTF();
                    String battleLogLevel = buffer.readUTF();
                    boolean battleTimeoutToAI = buffer.readBoolean();
                    LogUtils.info("活动服收到主服GM日志设置 -> logLevel:" + logLevel + ", battleLogLevel:" + battleLogLevel + ", battleTimeoutToAI:" + battleTimeoutToAI);
                    try{
                        ConfigFactory.gmSetting.setActivityLog(LogUtils.LOG_LEVEL.valueOf(logLevel));
                        ConfigFactory.gmSetting.setBattleTimeoutToAI(battleTimeoutToAI);

                        LogUtils.setLogLevel(ConfigFactory.gmSetting.getActivityLog());

                        ConfigFactory.gmSetting.setActivityBattleLog(LogUtils.LOG_LEVEL.valueOf(battleLogLevel));
                        GameServer.getInstance().sendToBattleServerLogConfig();
                    }catch (Exception e){
                        LogUtils.warn("设置测试配置出错 -> " + logLevel);
                    }
                }
            }
//            else if(CodeFactory.STOP_SERVER == code)
//            {
//                LogUtils.info("游戏主服务器关闭,我也要关闭了!");
//                GameServer.getInstance().stop();
//            }
        }catch (Exception e) {
            e.printStackTrace();
        }finally {
            byteBuf.release();
        }

    }

    @Override
    public void channelReadComplete(ChannelHandlerContext ctx) throws Exception {
        ctx.flush();// 将消息发送队列中的消息写入到SocketChannel中发送给对方。
    }


    @Override
    public void channelActive(ChannelHandlerContext ctx) throws Exception
    {
        LogUtils.info("活动服务器连接主服务器成功 -> " + serverInfo);

        serverInfo.setChannel(ctx.channel());

        ActivityCampManager activityCampManager = GameServer.getInstance().getActivityCampManager();
        JSONObject jsonObject = new JSONObject();
        jsonObject.put(ConstantFactory.MAX_WIN_COUNT_PLAYER, activityCampManager.getMaxWinCountPlayer());
        jsonObject.put(ConstantFactory.MAX_CONTINUE_WIN_PLAYER, activityCampManager.getMaxContinueWinPlayer());
        jsonObject.put(ConstantFactory.MAX_EXPLOIT_PLAYER, activityCampManager.getMaxExploitPlayer());
        jsonObject.put(ConstantFactory.RANK_PLAYER_LIST, activityCampManager.getRankPlayerList());
        jsonObject.put(ConstantFactory.RANK_CAMP_LIST, activityCampManager.getRankCampList());
        jsonObject.put(ConstantFactory.ACTIVITY_SERVER_HTTP, SpringContext.getHTTPServerPort());
        jsonObject.put(ConstantFactory.ACTIVITY_INDEX, activityCampManager.getIndex());
        jsonObject.put(ConstantFactory.APPLY_PLAYER_LIST, activityCampManager.getApplyPlayerList(serverInfo.getId()));
        jsonObject.put(ConstantFactory.ACTIVITY_STATUS, activityCampManager.getStatus());

        ActivityCampModel activityCampModel = null;
        for(int i = 0; i < 50; i++)
        {
            TimeUtils.sleep(1000);

            activityCampModel = activityCampManager.getActivityCampModel();
            if(activityCampModel != null)
            {
                LogUtils.info("发送活动时间给主服务器 -> " + serverInfo);
                serverInfo.sendCampActivityTime();
                break;
            }
        }

        ByteBuffer buffer = new ByteBuffer();
        buffer.writeUTF(jsonObject.toJSONString());

        SendUtils.sendMsg(ctx.channel(), CodeFactory.ACTIVITY_SERVER_INIT, buffer.getBytes());
    }


    @Override
    public void channelInactive(ChannelHandlerContext ctx) throws Exception
    {
        serverInfo.stop();

        ctx.close();
    }



}